﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FeiYang
{
    public  class 路径_
    {
        public 路径_ 上个;
        public 快捷传送_ 当前传送;
        public 地图_ 目标地图;
        public 坐标_ 目标地图内的点;
        public int 深度;
    }

    public class 门点及目标_
    {
        public 快捷传送_ 传送门;
        public 地图_ 目标;
    }

    public  class 路径计算_
    {
        public static Stack<门点及目标_> 计算(地图_ 起点, 地图_ 目标, 挂机人物_ 人物)
        {
            if (目标 == null)
            {
                人物.输出("这会错误");
            }
            if (起点 == 目标) return new Stack<门点及目标_>();
            if (目标.飞书传送 != null)
            {
                var 结果 = 目标.飞书传送(人物);
                if (结果) return new Stack<门点及目标_>();
            }

            var 走过的路径 = new Dictionary<string, 路径_>();
            路径_ 起始路径 = new 路径_();
            List<路径_> 结果组 = new List<路径_>();

            if (起点 != 地图_.跃马大平原 && 起点.分类 != 目标.分类)
            { 
                if (目标.分类 == 地图分类_.炼狱三职业_)
                {
                    起始路径.当前传送 = UI_.去炼狱旋涡;
                    起始路径.深度 = 0;
                    走过的路径.Add(UI_.去炼狱旋涡.名称, 起始路径);
                    起点 = 地图_.跃马大平原;
                }
                else if (目标.分类 == 地图分类_.沙城仓库_)
                {
                    起始路径.当前传送 = UI_.去拉镖活动;
                    起始路径.深度 = 0;
                    走过的路径.Add(UI_.去拉镖活动.名称, 起始路径);
                    起点 = 地图_.跃马大平原;
                }
                else if (目标 == 地图_.跃马大平原)
                {
                    快捷传送_ 传送 = UI_.去马倌;
                    if (人物.当前要去的点 != null)
                    {
                        var 点 = 人物.当前要去的点;
                        if (点 == 地图_.王城公告牌)
                        {
                            传送 = UI_.去王城任务;
                        }
                        if (点 == 地图_.炼狱旋涡 || 点== 地图_.土城铁匠)
                        {
                            传送 = UI_.去炼狱旋涡;
                        }
                        else if (点 == 地图_.声望老人 || 点 == 地图_.武馆教头) 
                        {
                            传送 = UI_.去声望老人;
                        }
                        else if ( 点 == 地图_.城主雕像  || 点 == 地图_.土城镖师 
                            || 点 == 地图_.土城去沙城仓库  || 点 == 地图_.沙城药商)
                        {
                            传送 = UI_.去拉镖活动;
                        }
                    }
                    起始路径.当前传送 = 传送;
                    起始路径.深度 = 0;
                    起始路径.目标地图 = 目标;
                    return 转为栈结果(起始路径);
                }
                else
                {
                    起始路径.当前传送 = UI_.去马倌;
                    起始路径.深度 = 0;
                    走过的路径.Add(UI_.去马倌.名称, 起始路径);
                    起点 = 地图_.老兵.目标地图.Find((地图_ a) => a.分类 == 目标.分类);
                }
            }
           
            内部计算(起点,  起始路径);

            return 转为栈结果(结果组.OrderBy(p => p.深度).FirstOrDefault());


            void 内部计算(地图_ 开始地图,  路径_ 路径)
            {
                // if (开始地图.分类 != 目标.分类) throw new Exception("尝试计算错误路径");
                if (开始地图 == 目标)
                {
                    路径.目标地图 = 开始地图;
                    结果组.Add(路径);
                    return;
                }
                foreach (var 传送 in 开始地图.获取所有门点())
                {
                    if (走过的路径.ContainsKey(传送.名称)) return;

                    if (路径.当前传送 != null) 路径.目标地图 = 开始地图;
                    var 当前 = new 路径_();
                    当前.深度 = 路径.当前传送 != null? 路径.深度 + 1: 0;
                    当前.当前传送 = 传送;
                    当前.上个 = 路径;
                    走过的路径.Add(当前.当前传送.名称, 当前);
                    foreach (var tt in 传送.目标地图)
                    {
                        if (tt.分类 == 目标.分类)
                        {
                            内部计算(tt, 当前);
                        }
                    }
                }
            }

            Stack<门点及目标_> 转为栈结果(路径_ 排序路径)
            {
                坐标_ 落点 = null;
                Stack<门点及目标_> 门点及目标 = new Stack<门点及目标_>();
                while (排序路径 != null && 排序路径.当前传送 != null)
                {
                    var 目标地图 = 排序路径.目标地图;
                    if (目标地图.飞书传送 != null)
                    {
                        var 到达 = 目标地图.飞书传送(人物);
                        if (到达) return 门点及目标;
                    }
                    var 当前门点及目标 = new 门点及目标_();
                    当前门点及目标.传送门 = 排序路径.当前传送;
                    if (排序路径.当前传送 != null && 排序路径.当前传送.位置 != null)
                    {
                        落点 = 排序路径.当前传送.位置.坐标;
                    }
                    当前门点及目标.目标 = 目标地图;
                    门点及目标.Push(当前门点及目标);
                    排序路径 = 排序路径.上个;
                }
                return 门点及目标;
            }
        }
    }
}
